package com.yantong.service.impl;


import com.yantong.constant.PermisFlag;
import com.yantong.utils.Tree;
import com.yantong.mapper.PermMapper;
import com.yantong.pojo.Permission;
import com.yantong.mapper.RolePermMapper;
import com.yantong.service.MenuService;
import com.yantong.utils.BuildTree;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author kanghaixin
 */
@SuppressWarnings("AlibabaRemoveCommentedCode")
@Service
@Transactional(rollbackFor = Exception.class)
public class MenuServiceImpl implements MenuService {
	private static final String MENU_CACHE_NAME = "menu";
	private static final Logger logger = LoggerFactory.getLogger(MenuServiceImpl.class);
	@Autowired
	PermMapper permMapper;
	@Autowired
	RolePermMapper roleMenuMapper;

	/**
	 * 获取系统树形菜单
	 * @param id 用户ID
	 * @return 树形菜单
	 */
	@Cacheable(value = MENU_CACHE_NAME, keyGenerator = "localKeyGenerator")
	@Override
	public Tree<Permission> getSysMenuTree(Long id) {
		List<Tree<Permission>> trees = new ArrayList<>();
		List<Permission> list = permMapper.listMenuByUserId(id);
		for (Permission permission : list) {
			Tree<Permission> tree = new Tree<>();
			tree.setId(permission.getPermId().toString());
			tree.setParentId(permission.getParentId().toString());
			tree.setText(permission.getName());
			Map<String, Object> attributes = new HashMap<>(4);
			attributes.put("url", permission.getUrl());
			attributes.put("icon", permission.getIcon());
			tree.setAttributes(attributes);
			trees.add(tree);
		}
		// 默认顶级菜单为0，根据数据库实际情况调整
		return BuildTree.build(trees);
	}

	@Override
	@Cacheable(value = MENU_CACHE_NAME, keyGenerator = "localKeyGenerator")
	public List<Permission> listMenus(String flag) {
		Map<String,Object> params = new HashMap<>(2);
		if (PermisFlag.FLAG_CENTRE.equals(flag)) {
			/**平台拥有所有菜单资源**/
			params.put("flag", flag);
		}
		return permMapper.listPerms(params);
	}

	@Transactional(readOnly = false,rollbackFor = Exception.class)
	@Override
	@CacheEvict(value = MENU_CACHE_NAME, allEntries = true)
	public int removePerm(Long permId) {
		if (permId == null) {
			return 0;
		}
		return permMapper.removePerm(permId);
	}


	@Override
	@CacheEvict(value = MENU_CACHE_NAME, allEntries = true)
	public int savePerm(Permission permission) {
		if (permission == null) {
			return 0;
		}
		return  permMapper.savePerm(permission);
	}

	@CacheEvict(value = MENU_CACHE_NAME, allEntries = true)
	@Override
	public int updatePerm(Permission permission) {
		if (permission == null) {
			return 0;
		}
		if (permission.getPermId() == null) {
			logger.info("perm id is null, update failed!");
			return 0;
		}
		return permMapper.updatePerm(permission);
	}

	@Override
	@Cacheable(value = MENU_CACHE_NAME, keyGenerator = "localKeyGenerator")
	public Permission getPermById(Long permId) {
		return permMapper.getByKey(permId);
	}

	@Override
	public Tree<Permission> getPermTree(String flag) {
		List<Tree<Permission>> trees = new ArrayList<>();

		Map<String,Object> params = new HashMap<>(2);
		if (PermisFlag.FLAG_CENTRE.equals(flag)) {
			/**平台拥有所有菜单资源**/
			params.put("flag", flag);
		}

		List<Permission> permissions = permMapper.listPerms(params);
		for (Permission sysPermission : permissions) {
			Tree<Permission> tree = new Tree<>();
			tree.setId(sysPermission.getPermId().toString());
			tree.setParentId(sysPermission.getParentId().toString());
			tree.setText(sysPermission.getName());
			trees.add(tree);
		}
		// 默认顶级菜单为0，根据数据库实际情况调整
		return BuildTree.build(trees);
	}

	@Override
	public Tree<Permission> getTreeByRoleId(Long roleId, String flag) {
		// 根据roleId查询权限
		Map<String,Object> params = new HashMap<>(2);
		if (PermisFlag.FLAG_CENTRE.equals(flag)) {
			/**平台拥有所有菜单资源**/
			params.put("flag", flag);
		}
		List<Permission> menus = permMapper.listPerms(params);

		List<Long> menuIds = roleMenuMapper.listPermIdByRoleId(roleId);
		List<Long> temp = menuIds;
		for (Permission menu : menus) {
			if (temp.contains(menu.getParentId())) {
				menuIds.remove(menu.getParentId());
			}
		}
		List<Tree<Permission>> trees = new ArrayList<>();
		List<Permission> permissions = permMapper.listPerms(params);
		for (Permission sysPermission : permissions) {
			Tree<Permission> tree = new Tree<>();
			tree.setId(sysPermission.getPermId().toString());
			tree.setParentId(sysPermission.getParentId().toString());
			tree.setText(sysPermission.getName());
			Map<String, Object> state = new HashMap<>(16);
			Long menuId = sysPermission.getPermId();
			if (menuIds.contains(menuId)) {
				state.put("selected", true);
			} else {
				state.put("selected", false);
			}
			tree.setState(state);
			trees.add(tree);
		}
		// 默认顶级菜单为０，根据数据库实际情况调整
		return BuildTree.build(trees);
	}

	@Override
	@Cacheable(value = MENU_CACHE_NAME, keyGenerator = "localKeyGenerator")
	public Set<String> getPermsByUserId(Long userId) {
		List<String> perms = permMapper.getUserPerms(userId);
		Set<String> permsSet = new HashSet<>();
		for (String perm : perms) {
			if (StringUtils.isNotBlank(perm)) {
				permsSet.addAll(Arrays.asList(perm.trim().split(",")));
			}
		}
		return permsSet;
	}

	/**
	 * 菜单树形结构，无root节点
	 * @param id
     * @return
     */
	@Override
	public List<Tree<Permission>> listMenuTree(Long id) {
		List<Tree<Permission>> trees = new ArrayList<>();
		List<Permission> list = permMapper.listMenuByUserId(id);

		for (Permission sysPermission : list) {
			Tree<Permission> tree = new Tree<>();
			tree.setId(sysPermission.getPermId().toString());
			tree.setParentId(sysPermission.getParentId().toString());
			tree.setText(sysPermission.getName());
			Map<String, Object> attributes = new HashMap<>(2);
			attributes.put("url", sysPermission.getUrl());
			attributes.put("icon", sysPermission.getIcon());
			tree.setAttributes(attributes);
			trees.add(tree);
		}
		// 默认顶级菜单为0,根据数据库实际情况调整
		return BuildTree.buildList(trees, "0");
	}
}
